Release 10.1A: OpenEdge Development:
Progress 4GL Handbook
Handling the ERROR condition
Your application can encounter an error condition whenever Progress cannot execute a statement properly, such as trying to find a record that does not exist or create a record with a duplicate value in a unique index. Progress has a built-in error message associated with each such error condition and, by default, displays it (or writes it to an error log on an AppServer).
For example, if your procedure executes a
FINDstatement for a nonexistent Customer, you get the error shown in Figure 17–10.Figure 17–10: FIND error message
![]()
The error number in parentheses lets you locate the message number under the Help menu to get more information on the error. It can also help you when you are reporting unexpected errors to technical support.
You can also generate the
ERRORcondition programmatically using theRETURN ERRORstatement, either as part of theONphrase of a block header or as a statement of its own. If your application has associated a keyboard key with theERRORcondition then Progress also raisesERRORwhen the user presses that key.ERROR-STATUS system handle
In most cases, you do not want raw error messages to be shown to users, even when it is their mistake that causes the error. The alert box in Figure 17–10, for example, is not a very friendly or informative way to present an error to a user. Even more important, it is essential that your procedures anticipate all possible error conditions whether they are caused by a user action or not, and respond to them, in some cases by suppressing an error message altogether. In addition, your application must define a mechanism for returning errors generated in an AppServer session back to the client, because by default Progress messages simply go to the server log file and are never seen.
To check for errors programmatically, you use the
ERROR-STATUSsystem handle. Many Progress statements support theNO-ERRORoption as the last keyword in the statement. If you specify this option, that statement does not generate theERRORcondition. Instead, if the statement cannot execute properly, execution continues with the next statement. You can then check whether an error occurred by examining the attributes of theERROR-STATUSsystem handle.The
ERROR-STATUShandle contains information on the last statement executed with theNO-ERRORoption. The logical attributeERROR-STATUS:ERRORtells you whether an error occurred. Because in some cases a single error can return multiple messages, theNUM-MESSAGESattribute tells you how many messages there are. TheGET-MESSAGE(<msg-num>)method returns the text of the message, and theGET-NUMBER(msg-num)method returns the internal message number. Here’s a simple example:
Because there is no Customer 9876, you get an error and your code displays the message box shown in Figure 17–11.
Figure 17–11: Example error message
![]()
Because you are intercepting the error, you can handle it more gracefully than this and also have your program logic proceed accordingly. You can check the message number using the
GET-NUMBERmethod and put code in your application to deal with each of the possible error conditions.Remember also that Progress provides special built-in functions, such as
AVAILABLEandLOCKED, to make it easier for you to tell when certain common errors have occurred:
Figure 17–12 shows the result.
Figure 17–12: Example information message
![]()
Note that the
ERROR-STATUShandle holds only error conditions and messages for the most recently executed statement with theNO-ERRORoption. It does not accumulate errors over multiple statements. TheERROR-STATUSremains in effect (and checkable by your code) until the next statement with theNO-ERRORoption.When the
ERRORcondition occurs anywhere outside of a trigger block, Progress looks for the closest block with the error property and undoes and retries that block. As discussed earlier, if it is not meaningful to retry the block. Progress proceeds to the next iteration if it is a repeating block or else leaves the block.Because this is the default, the following transaction header from the sample
saveOrderprocedure could simply beDO TRANSACTION: and have the same effect:
Error handling
If an error occurs in a database trigger block, Progress undoes the trigger block and returns
ERROR.If you use the
NO-ERRORoption on statements within a block, you are suppressing not only the visible error message but also theERRORcondition itself. Therefore, if you do this, it becomes your responsibility to check for errors and respond to them correctly. This might include issuing anUNDOstatement of your own. TheONphrase in the header simply changes the default action for untrapped conditions.RETURN statement and ON . . . RETURN phrase
In any
RETURNstatement, whether it returns anERRORor not, you can return a text string to the calling procedure. This string is accessible in the caller through theRETURN-VALUEbuilt-in function. Thus, a procedure can use a singleRETURNstatement to raise theERRORcondition in the caller, return a message, or both:
Likewise, the caller can check for the
ERROR-STATUS:ERRORcondition, or aRETURN-VALUE, or both, depending on the agreement between caller and callee as to how they communicate with one another. TheRETURN-VALUEfunction retains its value even through multipleRETURNstatements. Thus, while it is not required, it is advisable always to have aRETURNstatement at the end of every procedure, if only to clear theRETURN-VALUE. A simpleRETURNstatement is the same asRETURN “”. If you want to pass theRETURN-VALUEup the call stack, you should do this explicitly using the statementRETURN RETURN-VALUE.The same is true of the
RETURNoption as part of theONphrase in a block header. It can return a return-value, raiseERROR, or both.
|
Copyright © 2005 Progress Software Corporation www.progress.com Voice: (781) 280-4000 Fax: (781) 280-4095 |